; Disassembly of the file "Z:\home\knoppix\Public\LK.SYS" ; ; CPU Type: Z80 ; ; Using the opcode map file "Z:\home\knoppix\Public\LK.SYS.opmap" ; ; Created with dZ80 2.0 ; ; on Saturday, 31 of December 2016 at 08:22 PM ; 0000 E5 DEFB $E5 ; Unused area (E5 is opcode for PUSH HL) 0001 E5 DEFB $E5 ; This CP/M Loader is identical to CPM_CHRIS_Loader.asm 0002 E5 DEFB $E5 ; except this area is empty instead of having the code 0003 E5 DEFB $E5 ; for the PLUS logo 0004 E5 DEFB $E5 0005 E5 DEFB $E5 0006 E5 DEFB $E5 0007 E5 DEFB $E5 0008 E5 DEFB $E5 0009 E5 DEFB $E5 000A E5 DEFB $E5 000B E5 DEFB $E5 000C E5 DEFB $E5 000D E5 DEFB $E5 000E E5 DEFB $E5 000F E5 DEFB $E5 0010 E5 DEFB $E5 0011 E5 DEFB $E5 0012 E5 DEFB $E5 0013 E5 DEFB $E5 0014 E5 DEFB $E5 0015 E5 DEFB $E5 0016 E5 DEFB $E5 0017 E5 DEFB $E5 0018 E5 DEFB $E5 0019 E5 DEFB $E5 001A E5 DEFB $E5 001B E5 DEFB $E5 001C E5 DEFB $E5 001D E5 DEFB $E5 001E E5 DEFB $E5 001F E5 DEFB $E5 0020 E5 DEFB $E5 0021 E5 DEFB $E5 0022 E5 DEFB $E5 0023 E5 DEFB $E5 0024 E5 DEFB $E5 0025 E5 DEFB $E5 0026 E5 DEFB $E5 0027 E5 DEFB $E5 0028 E5 DEFB $E5 0029 E5 DEFB $E5 002A E5 DEFB $E5 002B E5 DEFB $E5 002C E5 DEFB $E5 002D E5 DEFB $E5 002E E5 DEFB $E5 002F E5 DEFB $E5 0030 E5 DEFB $E5 0031 E5 DEFB $E5 0032 E5 DEFB $E5 0033 E5 DEFB $E5 0034 E5 DEFB $E5 0035 E5 DEFB $E5 0036 E5 DEFB $E5 0037 E5 DEFB $E5 0038 E5 DEFB $E5 0039 E5 DEFB $E5 003A E5 DEFB $E5 003B E5 DEFB $E5 003C E5 DEFB $E5 003D E5 DEFB $E5 003E E5 DEFB $E5 003F E5 DEFB $E5 0040 E5 DEFB $E5 0041 E5 DEFB $E5 0042 E5 DEFB $E5 0043 E5 DEFB $E5 0044 E5 DEFB $E5 0045 E5 DEFB $E5 0046 E5 DEFB $E5 0047 E5 DEFB $E5 0048 E5 DEFB $E5 0049 E5 DEFB $E5 004A E5 DEFB $E5 004B E5 DEFB $E5 004C E5 DEFB $E5 004D E5 DEFB $E5 004E E5 DEFB $E5 004F E5 DEFB $E5 0050 E5 DEFB $E5 0051 E5 DEFB $E5 0052 E5 DEFB $E5 0053 E5 DEFB $E5 0054 E5 DEFB $E5 0055 E5 DEFB $E5 0056 E5 DEFB $E5 0057 E5 DEFB $E5 0058 E5 DEFB $E5 0059 E5 DEFB $E5 005A E5 DEFB $E5 005B E5 DEFB $E5 005C E5 DEFB $E5 005D E5 DEFB $E5 005E E5 DEFB $E5 005F E5 DEFB $E5 0060 E5 DEFB $E5 0061 E5 DEFB $E5 0062 E5 DEFB $E5 0063 E5 DEFB $E5 0064 E5 DEFB $E5 0065 E5 DEFB $E5 0066 E5 DEFB $E5 0067 E5 DEFB $E5 0068 E5 DEFB $E5 0069 E5 DEFB $E5 006A E5 DEFB $E5 006B E5 DEFB $E5 006C E5 DEFB $E5 006D E5 DEFB $E5 006E E5 DEFB $E5 006F E5 DEFB $E5 0070 E5 DEFB $E5 0071 E5 DEFB $E5 0072 E5 DEFB $E5 0073 E5 DEFB $E5 0074 E5 DEFB $E5 0075 E5 DEFB $E5 0076 E5 DEFB $E5 0077 E5 DEFB $E5 0078 E5 DEFB $E5 0079 E5 DEFB $E5 007A E5 DEFB $E5 007B E5 DEFB $E5 007C E5 DEFB $E5 007D E5 DEFB $E5 007E E5 DEFB $E5 007F E5 DEFB $E5 ; ######### From this point on the code is identical to CPM_CHRIS_Loader 0080 EB EX DE,HL ; DE=$0000 because, when BOOT ROM CP/M loading routine terminates, HL=$0000 0081 2A9A00 LD HL,($009A) ; HL=$0400 0084 4B LD C,E ; C=$00 0085 44 LD B,H ; B=$04 0086 EDB8 LDDR ; copy $0400-$0001 to $0000-$FC01; when done BC=$0000, DE=$FC00, HL=$0000 0088 EB EX DE,HL ; DE=$0000, HL=$FC00 0089 CBE5 SET 4,L ; HL=$FC10 008B CBFD SET 7,L ; HL=$FC90 008D E9 JP (HL) ; jump to $FC90 which is 0090 below --->| ; | 008E 00 DEFB $00 ; | 008F 00 DEFB $00 ; | ; | 0090 1820 JR $00B2 ; <--- <---|<--- <--- <--- <--- <--- <--| <---- CTC0 Interrupt Vector (unused) ; | 0092 09 DEFB $09 ;FC92 | \ CTC1 Interrupt 0093 FD DEFB $FD ;FC93 | / Vector 0094 FC DEFB $FC ;FC94 | \ CTC2 Interrupt 0095 FC DEFB $FC ;FC95 | / Vector 0096 00 DEFB $00 ;FC96 | \ CTC3 Interrupt (not 0097 20 DEFB $20 ;FC97 | / Vector used) <--- this is multiplier of $100 to give total size of a track both sides 0098 FF DEFB $FF ;FC98 | \ Start (top) address for saving 0099 3F DEFB $3F ;FC99 | / system track #0 data - in reverse !! 009A 00 DEFB $00 ;FC9A | \ Here TRACK_READ will save the start (top) address ($1FFF) 009B 04 DEFB $04 ;FC9B | / for saving system track #1 data in reverse, after track #0 is already saved 009C 03 DEFB $03 ;FC9C | \ 8272 Specify command opcode 009D 03 DEFB $03 ;FC9D | / 3 loops for 8272_CMD (2 args required after Specify command opcode) 009E 08 DEFB $08 ;FC9E | \ 8272 Sense Interrupt Status command opcode 009F 01 DEFB $01 ;FC9F | / 1 loop for 8272_CMD (no args required for SIS cmd) 00A0 04 DEFB $04 ;FCA0 | \ 8272 Sense Drive Status command opcode 00A1 02 DEFB $02 ;FCA1 | / 2 loops for 8272_CMD (1 arg required after Sense Drive Status command opcode) 00A2 0F DEFB $0F ;FCA2 | \ 8272 Seek command opcode 00A3 03 DEFB $03 ;FCA3 | / 3 loops for 8272_CMD (2 args required after Seek command opcode) 00A4 4A DEFB $4A ;FCA4 | \ 8272 Read ID command opcode with MFM 00A5 02 DEFB $02 ;FCA5 | / 2 loops for 8272_CMD (1 arg required after opcode) 00A6 C6 DEFB $C6 ; | \ 8272 Read Data command opcode with MFM and MT(MultiTrack) 00A7 09 DEFB $09 ; | / 9 loops for 8272_CMD (8 args required after Read Data command opcode) 00A8 EF DEFB $EF ;FCA8 | arg #1 for 8272 Specify cmd: SRT+HUT (Step Rate Time = 2 ms, Head Unload Time = 240 ms) 00A9 FF DEFB $FF ;FCA9 *** | arg #2 for 8272 Specify cmd: HLT+ND (Head Load Time = 254 ms, Non-DMA = 1) *** This is different from CPM+CHRIS_Loader 00AA 00 DEFB $00 ;FCAA | arg #1 for 8272 Seek cmd: (HDS+DS1+DS0) HDS kept on 0 while DS1+DS2 incremented 00AB 00 DEFB $00 ;FCAB | C = cylinder number 00AC 00 DEFB $00 ;FCAC | H = head number 00AD 00 DEFB $00 ;FCAD | R = sector number 00AE 00 DEFB $00 ;FCAE | N = bytes/sector 00AF 00 DEFB $00 ;FCAF | EOT 00B0 FF DEFB $FF ;FCB0 | GPL 00B1 FF DEFB $FF ;FCB1 | DTL ; | 00B2 F3 DI ; <--- <---| LATER USED FOR 8272 CMD RESULT STORAGE - $FCB2-$FCB8 <--- this is at $FCB2 when executed 00B3 F9 LD SP,HL ; HL=$FC90, set stack at $FC90 $FCB2-$FCB8 00B4 ED5E IM 2 ; interrupt mode 2 $FCB2-$FCB8 00B6 7C LD A,H ; A=$FC $FCB2-$FCB8 00B7 ED47 LD I,A ; I=$FC = upper half of CTC interrupt vector address $FCB2-$FCB8 00B9 7D LD A,L ; A=$90 = lower half of CTC interrupt vector address ... 00BA D3E3 OUT ($E3),A ; ... is sent to CTC channel 0 (bit 0 = 0 means Vector) ; MEANING: Interrupt Vector being used by all 4 channels!! ; Interrupt Vector = 10010cc0 where cc is the CTC channel requesting the interrupt. ; So vector for CTC0 = $90, CTC1 = $92, CTC2 = $94, CTC3 = $96 ; The upper half of addr table pointer is $FC which is $00 within this CP/M loader (after relocation, $0000 is at $FC00). 00BC 3EFF LD A,$FF ; Control word for CTC0 on next line (Enable Interrupt, Counter Mode, Rising Edge, Time Const. Follows, Reset, Control). ; MEANING: Reset, Enable Interrupts for Channel 0, a Time Constant follows. 00BE D3E3 OUT ($E3),A ; Write control word $FF to CTC channel 0 00C0 3E01 LD A,$01 ; Time constant for CTC0 on next line: ; MEANING: CTC0 generates INT for each byte transferred from 8272 to µP 00C2 D3E3 OUT ($E3),A ; Write time constant $01 to CTC channel 0 00C4 3E7B LD A,$7B ; Control word for CTC Channel 3 on next line (Disable Interrupt, Counter Mode, Rising Edge, No Time Constant Follows, Reset, Control) ; MEANING: Reset, Disable Interrupts for Channel 3 00C6 D3FB OUT ($FB),A ; Send control word to CTC Channel 3 00C8 2A92FC LD HL,($FC92) ; HL=$FD09 = interrupt vector for the routine call below (address of CTC1 Interrupt Service Routine) 00CB CD0CFD CALL $FD0C ; Call CTC1+2_INIT (deactivates CTC0 int. routine) 00CE CD4FFD CALL $FD4F ; Call 8272_READ to read command result bytes from 8272 Data Register (to make sure there's no unfinished command) 00D1 21A8FC LD HL,$FCA8 ; addr for the 2 Specify command args 00D4 ED4B9CFC LD BC,($FC9C) ; B=$03 (2 args after 8272 cmd opcode), C=$03 (8272 Specify command opcode) 00D8 CD2FFD CALL $FD2F ; Call 8272_CMD_HL to send Specify command to 8272 00DB D9 EXX ; #------------------------------# <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <---| 00DC ED4BA0FC LD BC,($FCA0) ; B=$02 (1 arg after 8272 cmd opcode), C=$04 (8272 Sense Drive Status command opcode) | 00E0 CD2CFD CALL $FD2C ; Call 8272_CMD to send Sense Drive Status command to 8272 | 00E3 CD4FFD CALL $FD4F ; Call 8272_READ to read command result bytes from 8272 Data Register | 00E6 CB6F BIT 5,A ; test bit 5 of ST3 (status of RDY signal from FDD,should be 1(?) if READY) | 00E8 D9 EXX ; #------------------------------# | 00E9 2005 JR NZ,$00F0 ; jump if FDD Ready --> -->| | 00EB 34 INC (HL) ; HL=$FCA8+2=$FCAA after the call to 8272_CMD_HL 8 lines above, ($FCAA)=00 initially=arg #1 for 8272 Seek cmd ** increment drive number ** 00EC CB96 RES 2,(HL) ; make sure HDS=0 for 8272 Seek cmd | 00EE 18EB JR $00DB ; ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> --->| 00F0 CD71FD CALL $FD71 ; <--- <--- <--- <--- <-----| call TRACK_READ, reads track 00 both sides 00F3 CD71FD CALL $FD71 ; call TRACK_READ, reads track 01 both sides 00F6 E9 JP (HL) ; ################ CTC0 Interrupt Service Routine (this reads floppy data bytes) ######## 00F7 EDA2 INI ; ----------------------- FCF7 after relocation ------------------------- 00F9 FB EI 00FA ED4D RETI ; ################ CTC2 Interrupt Service Routine ####################### 00FC E5 PUSH HL ; ----------------------- FCFC after relocation ------------------------- 00FD 2A92FC LD HL,($FC92) ; HL=$FD09 0100 2290FC LD ($FC90),HL ; ($FC90) = CTC0 Interrupt Service Routine addr = $FD09 = CTC1 Interrupt Service Routine (does nothing) *** this deactivates CTC0 routine *** 0103 21F0FC LD HL,$FCF0 ; location $FCF0 used as a flag: 0106 36FF LD (HL),$FF ; ($FCF0)=FF right after a track has been completely read 0108 E1 POP HL ; ################ CTC1 Interrupt Service Routine (does nothing) ######## 0109 FB EI ; ----------------------- FD09 after relocation ------------------------- 010A ED4D RETI ; ############################ CTC1+2_INIT ############################## 010C F3 DI ; ----------------------- FD0C after relocation ------------------------- 010D 2290FC LD ($FC90),HL ; set CTC0 interrupt vector to value in HL ($FD09 = CTC1 Interrupt Service Routine, does nothing) *** this deactivates CTC0 routine *** 0110 3E7F LD A,$7F ; Control word for CTC1 below (Disable Interrupt, Counter Mode, Rising Edge, Time Constant Follows, Reset, Control) ; MEANING: Reset, Disable Interrupts for Channel 1 0112 D3EB OUT ($EB),A ; Send control word to CTC channel 1 0114 3A96FC LD A,($FC96) ; A=$00 = time constant for CTC1 below ; MEANING: Channel 1 counts every 256 bytes transferred 0117 D3EB OUT ($EB),A ; Send time constant to CTC channel 1 0119 3EFF LD A,$FF ; Control word for CTC2 below (Enable Interrupt, Counter Mode, Rising Edge, Time Constant Follows, Reset, Control) ; MEANING: Reset, Enable Interrupts for Channel 2 011B D3F3 OUT ($F3),A ; Send control word to CTC channel 2 011D 3A97FC LD A,($FC97) ; A=$20 = time constant for CTC2 below ; MEANING: Channel 2 counts every $20 x $100 = $2000 = 8192 bytes transferred from 8272 (both sides of a system track, each having 1 sector with 4096 bytes) 0120 D3F3 OUT ($F3),A ; Send time constant to CTC channel 2 0122 C9 RET ; ############################ 8272_POLL ################################ ; ----------------------- FD23 after relocation ------------------------- 0123 DBF5 IN A,($F5) ; read 8272 Status Register <--- <--- <--- <--- <--- <-----| | this routine polls the 8272 Status Register 0125 CB7F BIT 7,A ; test bit 7 (RQM) to see if 8272 ready to send or receive | | until 8272 is ready to send or receive 0127 28FA JR Z,$0123 ; jump if 8272 not ready ---> ---> ---> ---> ---> ---> --->| | data to or from the CPU. When ready (RQM=1) 0129 CB77 BIT 6,A ; test bit 6 (DIO) to determine direction of data transfer | bit 6 is tested (DIO, 0=send/1=receive) 012B C9 RET ; ############################ 8272_CMD ################################## ; ----------------------- FD2C after relocation ------------------------- ; BC = parameter to this subroutine: B = loop count for DJNZ $0137, C = command opcode to write to 8272 Data Register 012C 21AAFC LD HL,$FCAA ; address of 8272 command parameter bytes following the command opcode ; ############################ 8272_CMD_HL ############################### ; ----------------------- FD2F after relocation ------------------------- ; this entry point requires HL = additional parameter as address of 8272 command parameter bytes following the command opcode 012F DBF5 IN A,($F5) ; read 8272 Status Register <----| 0131 CB67 BIT 4,A ; test bit 4 (FDC Busy) | 0133 20FA JR NZ,$012F; if FDC Busy jump ---> ---> --->| 0135 1802 JR $0139 ; ---> ---> --->| 0137 4E LD C,(HL) ; <---- <--- <--- <--- <--- <---| C = (next) 8272 cmd parameter byte 0138 23 INC HL ; | | increment 8272 cmd parameter pointer 0139 F3 DI ; <--- <--- <---| | 013A CD23FD CALL $FD23 ; Call 8272_POLL | 013D 2022 JR NZ,$0161; jump to CPM_TO_COBRA if transfer is TO CPU 013F 59 LD E,C ; E=8272 cmd byte | <<< this will leave E'=$02 when 8272_CMD is called from TRACK_READ at $0197 within this binary file 0140 0EFD LD C,$FD ; 8272 Data Register port addr | since the second command byte of Read ID will be $02 (CP/M boots from drive 2, head 0) 0142 ED59 OUT (C),E ; write to 8272 Data Register | (for later when CP/M starts with BIOS function 00 BOOT !!!!) 0144 10F1 DJNZ $0137 ; ----> ---> ---> ---> ---> --->| <<< this will leave C'=$02 when 8272_CMD is called from TRACK_READ at $0197 within this binary file 0146 FB EI ; since the second command byte of Read ID will be $02 (CP/M boots from drive 2, head 0) 0147 C9 RET ; (for later when CP/M starts with BIOS function 00 BOOT !!!!) ; ############################ 8272_CMD_SIS ############################## ; ----------------------- FD48 after relocation ------------------------- 0148 ED4B9EFC LD BC,($FC9E) ; C=08=Sense Interrupt Status opcode, B=01=0 args req'd 014C CD2FFD CALL $FD2F ; Call 8272_CMD_HL to send Sense Interrupt Status cmd ; ############################ 8272_READ ################################# ; ----------------------- FD4F after relocation ------------------------- ; Read command result bytes from 8272 Data Register and store them at FCB2-FCB8. ; Normally max. 7 command result bytes can be read and normal exit is by jump at 0157 ; If after 7 bytes read the transfer direction detected does not change to "CPU -> 8272" ; then something is wrong and a jump is made to BOOT hw config (JR Z,$016C) 014F 21B2FC LD HL,$FCB2 0152 0608 LD B,$08 ; 8 loops next 0154 CD23FD CALL $FD23 ; Call 8272_POLL<--- <--- <--- <--- <---| 0157 2813 JR Z,$016C ; Jump if transfer is FROM CPU -----> ---> ---> --->| 0159 36FF LD (HL),$FF ; ($FCB2+nn)=FF | | 015B DBFD IN A,($FD) ; read 1 byte from 8272 Data Register | | 015D 77 LD (HL),A ; store byte at ($FCB2+nn) | | 015E 23 INC HL ; | | 015F 10F3 DJNZ $0154 ; ---> ---> ---> ---> ---> ---> ---> -->| | <<< this should leave B'=$01 for later when CP/M starts with BIOS function 00 BOOT !!!! 0161 F3 DI ; ############## CPM_TO_COBRA ############## | (7 result bytes are read after Read ID command) 0162 AF XOR A ; A=00 | 0163 6F LD L,A ; | 0164 67 LD H,A ; HL=0000 | 0165 F6C1 OR $C1 ; A=$C1 | 0167 D3FE OUT ($FE),A ; write $C1 to port C of 8255 | ; ; (set border to blue, set signal "SO" to 1, set signal "O5" to 0, ; ; set signal "O6" to 1 to allow access to video memory in the hw startup config) 0169 ED4F LD R,A ; set bit 7 of R to 1 to prepare jump to startup (COBRA BOOT) hw config 016B E9 JP (HL) ; jump to (HL)=$0000 | ; | 016C 21B2FC LD HL,$FCB2 ; <--- <--- <--- <--- <--- <--- <--- <--- <--- <---| <<< this leaves HL'=$FCB2 for later when CP/M starts with BIOS function 00 BOOT !!!! 016F 7E LD A,(HL) ; Load first command result byte in A 0170 C9 RET ; ############################ TRACK_READ ################################ ; ----------------------- FD71 after relocation ------------------------- 0171 ED4BA2FC LD BC,($FCA2) ; B=$03 (2 args after 8272 cmd opcode), C=$0F (8272 Seek command opcode) 0175 CD2CFD CALL $FD2C ; Call 8272_CMD to send Seek command to 8272 0178 CD48FD CALL $FD48 ; Call 8272_CMD_SIS <--- <--- <--- <--- <--- <--- <-| 017B CB6F BIT 5,A ; Test bit 5 of result ST0, SE byte = Seek End | 017D 28F9 JR Z,$0178 ; Jump if Seek not finished ---> ---> ---> ---> --->| 017F E650 AND $50 0181 20DE JR NZ,$0161 ; Jump to CPM_TO_COBRA if HD or US0 are 1 0183 CD48FD CALL $FD48 ; Call 8272_CMD_SIS <--- <--- <---| 0186 FE80 CP $80 ; Check if Invalid Command issue | (check if SIS ended abnormally) 0188 20F9 JR NZ,$0183 ; jump if not ---> ---> ---> --->| ; *** the above loop goes until SIS becomes Invalid Command because it does not immediately follow a Seek or Recalibrate command ; *** it is used as No-Op command, to place the FDC in a standby or no operation state. 018A DBF5 IN A,($F5) ; read 8272 Status Register <--- <--- <--- <-----| 018C E60F AND $0F ; Check if any FDD is in Seek Mode (Main Status Register bits 0-3) 018E 20FA JR NZ,$018A ; jump if any FDD is in Seek Mode ---> ---> --->| 0190 0603 LD B,$03 ; loop counter - next loop goes 3 times 0192 D9 EXX ; <---- <--- <--- <--- <--- <---| 0193 ED4BA4FC LD BC,($FCA4) ; B=$02 (1 arg after 8272 cmd opcode), C=$4A (8272 Read ID command opcode with MFM) 0197 CD2CFD CALL $FD2C ; Call 8272_CMD to send Read ID command to 8272 019A CD4FFD CALL $FD4F ; Call 8272_READ and save | Read ID result bytes at $FCB2-$FCB8 019D E6C0 AND $C0 ; Check for Abnormal Termination (bits 6-7 of ST0) 019F D9 EXX ; | 01A0 2804 JR Z,$01A6 ; jump if normal termination ------> --->| 01A2 10EE DJNZ $0192 ; ----> ---> ---> ---> ---> --->| 3 attempts to read a proper ID Address Mark from disk 01A4 18BB JR $0161 ; Jump to CPM_TO_COBRA | 01A6 21B5FC LD HL,$FCB5 ; <---- <---- <---- <---- <---- <---- <-| 01A9 11ABFC LD DE,$FCAB 01AC 010400 LD BC,$0004 01AF EDB0 LDIR ; copy the last 4 Read ID result bytes from $FCB2-$FCB8 to $FCAB-$FCAE (C, H, R, N) *** when done, HL=$FCB9, DE=$FCAF *** 01B1 2B DEC HL ; HL=$FCB8 01B2 46 LD B,(HL) ; B = 4th Read ID result byte: N (bytes/sector) which is 5 (128x2^5=4096) for this stupidly "protected" system 01B3 2B DEC HL ; HL=$FCB7 01B4 7E LD A,(HL) ; A = 3rd Read ID result byte: R (sector number) 01B5 12 LD (DE),A ; ($FCAF)=sector number 01B6 C5 PUSH BC ; *** SAVE BC *** <---- <---- <---- <---- <---- <---- <---- <----| this loop goes N=5 times or until no error occured while reading 01B7 AF XOR A ; A=00 | 01B8 32F0FC LD ($FCF0),A ; ($FCF0)=$00 location $FCF0 used as a flag: ($FCF0)=FF right after a track has been completely read 01BB 21F7FC LD HL,$FCF7 ; value for set CTC0 interrupt vector to, when CTC1+2_INIT is called next 01BE CD0CFD CALL $FD0C ; Call CTC1+2_INIT - sets CTC0 interrupt vector to $FCF7 | 01C1 23 INC HL ; HL=$FCF8, ($FCF8)=$A2=part of the opcode for the INI instruction | 01C2 CBDE SET 3,(HL) ; now ($FCF8)=$AA, so at $FCF7 now we have the opcode $EDAA which is the Z80 instruction IND (instead of INI) - some smart way to hide the fact that system sectors are written in reverse on disk !!! 01C4 ED4BA6FC LD BC,($FCA6) ; B=$09, C=$C6 (8272 Read Data command opcode with MFM and MT(MultiTrack)) 01C8 CD2CFD CALL $FD2C ; Call 8272_CMD to send Read Data command to 8272 | 01CB 2A98FC LD HL,($FC98) ; HL=$3FFF = top address for saving system tracks data (sectors read normally but saving to mem will be done downwards, to $0000) 01CE 76 HALT ; <---- <---- <---- <---- <---- <-----| during this loop both sides of one system track (2 sectors x 4096 bytes each) are read from disk and saved to mem 01CF DBF5 IN A,($F5) ; read 8272 Status Register | | 01D1 E620 AND $20 ; test bit 5 (0 means non-DMA execution phase has ended) | 01D3 20F9 JR NZ,$01CE ; jump if not ended ----> ----> ---->| | 01D5 229AFC LD ($FC9A),HL ; save the current sector data saving address for next system track, to ($FC9A-$FC9B) 01D8 2A92FC LD HL,($FC92) ; HL=FD09 = interrupt vector for the routine call below (address of CTC1 Interrupt Service Routine) 01DB CD0CFD CALL $FD0C ; Call CTC1+2_INIT - sets CTC0 interrupt vector to $FD09 (disables CTC0 Interrupt Service Routine) 01DE CD4FFD CALL $FD4F ; Call 8272_READ and save result bytes at FCB2-FCB8 | 01E1 3AF0FC LD A,($FCF0) ; FLAG byte = FF right after a track has been completely read | 01E4 B7 OR A ; test if FLAG byte = 00 (track still being read) | 01E5 C1 POP BC ; *** RESTORE BC *** | 01E6 2805 JR Z,$01ED ; ----> ----> ----> ----> ----> ----> ---->| | 01E8 7E LD A,(HL) ; A=(FCB2) first Read Data result byte | which is ST0 | 01E9 E6D8 AND $D8 ; check error bits in ST0 | | 01EB 2805 JR Z,$01F2 ; jump if no error--> ---->| | | 01ED 10C7 DJNZ $01B6 ; ----> ----> ----> ----> ----> ----> ---->+----> ----> ----> ---->| 01EF C361FD JP $FD61 ; jump to CPM_TO_COBRA | (if reading errors occured) 01F2 21ABFC LD HL,$FCAB ; <----- <---- <---- <----| ($FCAB)=cylinder number (C, 4th Read ID result byte) 01F5 34 INC (HL) ; increment cylinder number 01F6 2A9AFC LD HL,($FC9A) ; HL = the current saving address 01F9 2298FC LD ($FC98),HL ; Overwrite the initial (top) saving address with the current one 01FC 23 INC HL ; When this routine is called the second time to read the second system track, ; at this point the current saving address in HL will be $0000 - 1 = $FFFF. ; So INC HL will bring it to $0000 since after the second call of this procedure ; a JP (HL) is executed (see the end of main code) to jumpstart the CP/M system. 01FD C9 RET 01FE 00 DEFB $00 01FF 00 DEFB $00 0200 55 DEFB $55 0201 73 DEFB $73 0202 65 DEFB $65 0203 72 DEFB $72 0204 20 DEFB $20 0205 24 DEFB $24 0206 2C DEFB $2C 0207 20 DEFB $20 0208 46 DEFB $46 0209 69 DEFB $69 020A 6C DEFB $6C 020B 65 DEFB $65 020C 20 DEFB $20 020D 6E DEFB $6E 020E 6F DEFB $6F 020F 74 DEFB $74 0210 20 DEFB $20 0211 66 DEFB $66 0212 6F DEFB $6F 0213 75 DEFB $75 0214 6E DEFB $6E 0215 64 DEFB $64 0216 24 DEFB $24 0217 20 DEFB $20 0218 44 DEFB $44 0219 72 DEFB $72 021A 69 DEFB $69 021B 76 DEFB $76 021C 65 DEFB $65 021D 3A DEFB $3A 021E 20 DEFB $20 021F 24 DEFB $24 0220 2C DEFB $2C 0221 20 DEFB $20 0222 55 DEFB $55 0223 73 DEFB $73 0224 65 DEFB $65 0225 72 DEFB $72 0226 3A DEFB $3A 0227 20 DEFB $20 0228 24 DEFB $24 0229 20 DEFB $20 022A 46 DEFB $46 022B 69 DEFB $69 022C 6C DEFB $6C 022D 65 DEFB $65 022E 20 DEFB $20 022F 43 DEFB $43 0230 6F DEFB $6F 0231 75 DEFB $75 0232 6E DEFB $6E 0233 74 DEFB $74 0234 3A DEFB $3A 0235 20 DEFB $20 0236 24 DEFB $24 0237 2C DEFB $2C 0238 20 DEFB $20 0239 24 DEFB $24 023A 46 DEFB $46 023B 72 DEFB $72 023C 65 DEFB $65 023D 65 DEFB $65 023E 20 DEFB $20 023F 52 DEFB $52 0240 2F DEFB $2F 0241 57 DEFB $57 0242 20 DEFB $20 0243 53 DEFB $53 0244 70 DEFB $70 0245 61 DEFB $61 0246 63 DEFB $63 0247 65 DEFB $65 0248 3A DEFB $3A 0249 20 DEFB $20 024A 24 DEFB $24 024B 46 DEFB $46 024C 69 DEFB $69 024D 6C DEFB $6C 024E 65 DEFB $65 024F 20 DEFB $20 0250 63 DEFB $63 0251 6C DEFB $6C 0252 6F DEFB $6F 0253 73 DEFB $73 0254 65 DEFB $65 0255 20 DEFB $20 0256 65 DEFB $65 0257 72 DEFB $72 0258 72 DEFB $72 0259 6F DEFB $6F 025A 72 DEFB $72 025B 24 DEFB $24 025C 54 DEFB $54 025D 79 DEFB $79 025E 70 DEFB $70 025F 65 DEFB $65 0260 20 DEFB $20 0261 43 DEFB $43 0262 6F DEFB $6F 0263 6E DEFB $6E 0264 74 DEFB $74 0265 72 DEFB $72 0266 6F DEFB $6F 0267 6C DEFB $6C 0268 2D DEFB $2D 0269 43 DEFB $43 026A 20 DEFB $20 026B 74 DEFB $74 026C 6F DEFB $6F 026D 20 DEFB $20 026E 71 DEFB $71 026F 75 DEFB $75 0270 69 DEFB $69 0271 74 DEFB $74 0272 2C DEFB $2C 0273 20 DEFB $20 0274 61 DEFB $61 0275 6E DEFB $6E 0276 79 DEFB $79 0277 20 DEFB $20 0278 6F DEFB $6F 0279 74 DEFB $74 027A 68 DEFB $68 027B 65 DEFB $65 027C 72 DEFB $72 027D 20 DEFB $20 027E 74 DEFB $74 027F 6F DEFB $6F 0280 20 DEFB $20 0281 63 DEFB $63 0282 6F DEFB $6F 0283 6E DEFB $6E 0284 74 DEFB $74 0285 69 DEFB $69 0286 6E DEFB $6E 0287 75 DEFB $75 0288 65 DEFB $65 0289 3A DEFB $3A 028A 20 DEFB $20 028B 24 DEFB $24 028C 5C DEFB $5C 028D 20 DEFB $20 028E 20 DEFB $20 028F 20 DEFB $20 0290 20 DEFB $20 0291 24 DEFB $24 0292 3A DEFB $3A 0293 20 DEFB $20 0294 44 DEFB $44 0295 72 DEFB $72 0296 69 DEFB $69 0297 76 DEFB $76 0298 65 DEFB $65 0299 20 DEFB $20 029A 43 DEFB $43 029B 68 DEFB $68 029C 61 DEFB $61 029D 72 DEFB $72 029E 61 DEFB $61 029F 63 DEFB $63 02A0 74 DEFB $74 02A1 65 DEFB $65 02A2 72 DEFB $72 02A3 69 DEFB $69 02A4 73 DEFB $73 02A5 74 DEFB $74 02A6 69 DEFB $69 02A7 63 DEFB $63 02A8 73 DEFB $73 02A9 5C DEFB $5C 02AA 24 DEFB $24 02AB 3A DEFB $3A 02AC 20 DEFB $20 02AD 31 DEFB $31 02AE 32 DEFB $32 02AF 38 DEFB $38 02B0 20 DEFB $20 02B1 42 DEFB $42 02B2 79 DEFB $79 02B3 74 DEFB $74 02B4 65 DEFB $65 02B5 20 DEFB $20 02B6 52 DEFB $52 02B7 65 DEFB $65 02B8 63 DEFB $63 02B9 6F DEFB $6F 02BA 72 DEFB $72 02BB 64 DEFB $64 02BC 20 DEFB $20 02BD 43 DEFB $43 02BE 61 DEFB $61 02BF 70 DEFB $70 02C0 61 DEFB $61 02C1 63 DEFB $63 02C2 69 DEFB $69 02C3 74 DEFB $74 02C4 79 DEFB $79 02C5 5C DEFB $5C 02C6 24 DEFB $24 02C7 3A DEFB $3A 02C8 20 DEFB $20 02C9 4B DEFB $4B 02CA 69 DEFB $69 02CB 6C DEFB $6C 02CC 6F DEFB $6F 02CD 62 DEFB $62 02CE 79 DEFB $79 02CF 74 DEFB $74 02D0 65 DEFB $65 02D1 20 DEFB $20 02D2 44 DEFB $44 02D3 72 DEFB $72 02D4 69 DEFB $69 02D5 76 DEFB $76 02D6 65 DEFB $65 02D7 20 DEFB $20 02D8 43 DEFB $43 02D9 61 DEFB $61 02DA 70 DEFB $70 02DB 61 DEFB $61 02DC 63 DEFB $63 02DD 69 DEFB $69 02DE 74 DEFB $74 02DF 79 DEFB $79 02E0 5C DEFB $5C 02E1 24 DEFB $24 02E2 3A DEFB $3A 02E3 20 DEFB $20 02E4 33 DEFB $33 02E5 32 DEFB $32 02E6 20 DEFB $20 02E7 42 DEFB $42 02E8 79 DEFB $79 02E9 74 DEFB $74 02EA 65 DEFB $65 02EB 20 DEFB $20 02EC 44 DEFB $44 02ED 69 DEFB $69 02EE 72 DEFB $72 02EF 65 DEFB $65 02F0 63 DEFB $63 02F1 74 DEFB $74 02F2 6F DEFB $6F 02F3 72 DEFB $72 02F4 79 DEFB $79 02F5 20 DEFB $20 02F6 45 DEFB $45 02F7 6E DEFB $6E 02F8 74 DEFB $74 02F9 72 DEFB $72 02FA 69 DEFB $69 02FB 65 DEFB $65 02FC 73 DEFB $73 02FD 5C DEFB $5C 02FE 24 DEFB $24 02FF 3A DEFB $3A 0300 20 DEFB $20 0301 43 DEFB $43 0302 68 DEFB $68 0303 65 DEFB $65 0304 63 DEFB $63 0305 6B DEFB $6B 0306 65 DEFB $65 0307 64 DEFB $64 0308 20 DEFB $20 0309 44 DEFB $44 030A 69 DEFB $69 030B 72 DEFB $72 030C 65 DEFB $65 030D 63 DEFB $63 030E 74 DEFB $74 030F 6F DEFB $6F 0310 72 DEFB $72 0311 79 DEFB $79 0312 20 DEFB $20 0313 45 DEFB $45 0314 6E DEFB $6E 0315 74 DEFB $74 0316 72 DEFB $72 0317 69 DEFB $69 0318 65 DEFB $65 0319 73 DEFB $73 031A 5C DEFB $5C 031B 24 DEFB $24 031C 3A DEFB $3A 031D 20 DEFB $20 031E 52 DEFB $52 031F 65 DEFB $65 0320 63 DEFB $63 0321 6F DEFB $6F 0322 72 DEFB $72 0323 64 DEFB $64 0324 73 DEFB $73 0325 2F DEFB $2F 0326 20 DEFB $20 0327 45 DEFB $45 0328 78 DEFB $78 0329 74 DEFB $74 032A 65 DEFB $65 032B 6E DEFB $6E 032C 74 DEFB $74 032D 5C DEFB $5C 032E 24 DEFB $24 032F 3A DEFB $3A 0330 20 DEFB $20 0331 52 DEFB $52 0332 65 DEFB $65 0333 63 DEFB $63 0334 6F DEFB $6F 0335 72 DEFB $72 0336 64 DEFB $64 0337 73 DEFB $73 0338 2F DEFB $2F 0339 20 DEFB $20 033A 42 DEFB $42 033B 6C DEFB $6C 033C 6F DEFB $6F 033D 63 DEFB $63 033E 6B DEFB $6B 033F 5C DEFB $5C 0340 24 DEFB $24 0341 3A DEFB $3A 0342 20 DEFB $20 0343 53 DEFB $53 0344 65 DEFB $65 0345 63 DEFB $63 0346 74 DEFB $74 0347 6F DEFB $6F 0348 72 DEFB $72 0349 73 DEFB $73 034A 2F DEFB $2F 034B 20 DEFB $20 034C 54 DEFB $54 034D 72 DEFB $72 034E 61 DEFB $61 034F 63 DEFB $63 0350 6B DEFB $6B 0351 5C DEFB $5C 0352 24 DEFB $24 0353 3A DEFB $3A 0354 20 DEFB $20 0355 52 DEFB $52 0356 65 DEFB $65 0357 73 DEFB $73 0358 65 DEFB $65 0359 72 DEFB $72 035A 76 DEFB $76 035B 65 DEFB $65 035C 64 DEFB $64 035D 20 DEFB $20 035E 54 DEFB $54 035F 72 DEFB $72 0360 61 DEFB $61 0361 63 DEFB $63 0362 6B DEFB $6B 0363 73 DEFB $73 0364 5C DEFB $5C 0365 24 DEFB $24 0366 70 DEFB $70 0367 72 DEFB $72 0368 69 DEFB $69 0369 6E DEFB $6E 036A 74 DEFB $74 036B 65 DEFB $65 036C 72 DEFB $72 036D 5C DEFB $5C 036E 24 DEFB $24 036F 66 DEFB $66 0370 69 DEFB $69 0371 6C DEFB $6C 0372 65 DEFB $65 0373 3A DEFB $3A 0374 20 DEFB $20 0375 24 DEFB $24 0376 5C DEFB $5C 0377 4F DEFB $4F 0378 75 DEFB $75 0379 74 DEFB $74 037A 70 DEFB $70 037B 75 DEFB $75 037C 74 DEFB $74 037D 20 DEFB $20 037E 64 DEFB $64 037F 69 DEFB $69 0380 72 DEFB $72 0381 65 DEFB $65 0382 63 DEFB $63 0383 74 DEFB $74 0384 65 DEFB $65 0385 64 DEFB $64 0386 20 DEFB $20 0387 74 DEFB $74 0388 6F DEFB $6F 0389 20 DEFB $20 038A 74 DEFB $74 038B 68 DEFB $68 038C 65 DEFB $65 038D 20 DEFB $20 038E 24 DEFB $24 038F 20 DEFB $20 0390 24 DEFB $24 0391 20 DEFB $20 0392 20 DEFB $20 0393 24 DEFB $24 0394 52 DEFB $52 0395 2F DEFB $2F 0396 4F DEFB $4F 0397 20 DEFB $20 0398 24 DEFB $24 0399 52 DEFB $52 039A 2F DEFB $2F 039B 57 DEFB $57 039C 20 DEFB $20 039D 24 DEFB $24 039E 53 DEFB $53 039F 59 DEFB $59 03A0 53 DEFB $53 03A1 20 DEFB $20 03A2 24 DEFB $24 03A3 44 DEFB $44 03A4 49 DEFB $49 03A5 52 DEFB $52 03A6 20 DEFB $20 03A7 24 DEFB $24 03A8 2C DEFB $2C 03A9 20 DEFB $20 03AA 53 DEFB $53 03AB 79 DEFB $79 03AC 73 DEFB $73 03AD 74 DEFB $74 03AE 65 DEFB $65 03AF 6D DEFB $6D 03B0 20 DEFB $20 03B1 46 DEFB $46 03B2 69 DEFB $69 03B3 6C DEFB $6C 03B4 65 DEFB $65 03B5 73 DEFB $73 03B6 20 DEFB $20 03B7 50 DEFB $50 03B8 72 DEFB $72 03B9 65 DEFB $65 03BA 73 DEFB $73 03BB 65 DEFB $65 03BC 6E DEFB $6E 03BD 74 DEFB $74 03BE 24 DEFB $24 03BF 5C DEFB $5C 03C0 49 DEFB $49 03C1 6E DEFB $6E 03C2 76 DEFB $76 03C3 61 DEFB $61 03C4 6C DEFB $6C 03C5 69 DEFB $69 03C6 64 DEFB $64 03C7 20 DEFB $20 03C8 46 DEFB $46 03C9 69 DEFB $69 03CA 6C DEFB $6C 03CB 65 DEFB $65 03CC 20 DEFB $20 03CD 4E DEFB $4E 03CE 61 DEFB $61 03CF 6D DEFB $6D 03D0 65 DEFB $65 03D1 20 DEFB $20 03D2 65 DEFB $65 03D3 72 DEFB $72 03D4 72 DEFB $72 03D5 6F DEFB $6F 03D6 72 DEFB $72 03D7 24 DEFB $24 03D8 5C DEFB $5C 03D9 49 DEFB $49 03DA 6E DEFB $6E 03DB 73 DEFB $73 03DC 75 DEFB $75 03DD 66 DEFB $66 03DE 66 DEFB $66 03DF 69 DEFB $69 03E0 63 DEFB $63 03E1 69 DEFB $69 03E2 65 DEFB $65 03E3 6E DEFB $6E 03E4 74 DEFB $74 03E5 20 DEFB $20 03E6 4D DEFB $4D 03E7 65 DEFB $65 03E8 6D DEFB $6D 03E9 6F DEFB $6F 03EA 72 DEFB $72 03EB 79 DEFB $79 03EC 20 DEFB $20 03ED 65 DEFB $65 03EE 72 DEFB $72 03EF 72 DEFB $72 03F0 6F DEFB $6F 03F1 72 DEFB $72 03F2 24 DEFB $24 03F3 5C DEFB $5C 03F4 2A DEFB $2A 03F5 2A DEFB $2A 03F6 20 DEFB $20 03F7 57 DEFB $57 03F8 41 DEFB $41 03F9 52 DEFB $52 03FA 4E DEFB $4E 03FB 49 DEFB $49 03FC 4E DEFB $4E 03FD 47 DEFB $47 03FE 20 DEFB $20 03FF 2A DEFB $2A 0400 1A LD A,(DE) ; ####### Useless code from here on most likely 0401 77 LD (HL),A 0402 23 INC HL 0403 56 LD D,(HL) 0404 77 LD (HL),A 0405 C9 RET 0406 FB EI 0407 3AF8FD LD A,($FDF8) 040A E603 AND $03 040C F630 OR $30 040E 329D72 LD ($729D),A 0411 CB4F BIT 1,A 0413 3E00 LD A,$00 0415 21EAF6 LD HL,$F6EA 0418 2805 JR Z,$041F 041A F640 OR $40 041C 21CAF6 LD HL,$F6CA 041F 2259F6 LD ($F659),HL 0422 224AFB LD ($FB4A),HL 0425 2B DEC HL 0426 56 LD D,(HL) 0427 2B DEC HL 0428 5E LD E,(HL) 0429 ED5340FB LD ($FB40),DE 042D CD906F CALL $6F90 0430 CD3F70 CALL $703F 0433 C5 PUSH BC 0434 F3 DI 0435 D9 EXX 0436 E1 POP HL 0437 B7 OR A 0438 ED52 SBC HL,DE 043A C8 RET Z 043B E1 POP HL 043C 2E00 LD L,$00 043E E9 JP (HL) 043F 21076E LD HL,$6E07 0442 F6FF OR $FF 0444 AE XOR (HL) 0445 C0 RET NZ 0446 77 LD (HL),A 0447 F6FF OR $FF 0449 32096E LD ($6E09),A 044C 3A56F6 LD A,($F656) 044F F605 OR $05 0451 2186F9 LD HL,$F986 0454 CBC6 SET 0,(HL) 0456 1811 JR $0469 0458 AF XOR A 0459 32036E LD ($6E03),A 045C 32096E LD ($6E09),A 045F 3A56F6 LD A,($F656) 0462 F606 OR $06 0464 2186F9 LD HL,$F986 0467 CB86 RES 0,(HL) 0469 4F LD C,A 046A E607 AND $07 046C 320A6E LD ($6E0A),A 046F 060A LD B,$0A 0471 C5 PUSH BC 0472 CD5871 CALL $7158 0475 AF XOR A 0476 325BF6 LD ($F65B),A 0479 CD39F6 CALL $F639 047C 2185F9 LD HL,$F985 047F 220000 LD ($0000),HL